package top.saplf.sileny.net.netease

import android.support.annotation.IntDef
import io.reactivex.Observable
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.ResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level.BODY
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.POST
import retrofit2.http.Query
import retrofit2.http.QueryMap
import retrofit2.http.Streaming
import top.saplf.sileny.net.netease.NetEaseService.ALBUM
import top.saplf.sileny.net.netease.NetEaseService.LRC
import top.saplf.sileny.net.netease.NetEaseService.MV
import top.saplf.sileny.net.netease.NetEaseService.SHEET
import top.saplf.sileny.net.netease.NetEaseService.SINGER
import top.saplf.sileny.net.netease.NetEaseService.SONG
import top.saplf.sileny.net.netease.NetEaseService.STATION
import top.saplf.sileny.net.netease.NetEaseService.USER

/**
 * @author saplf
 */

private val netEaseRetrofit: Retrofit by lazy {
    Retrofit.Builder()
            .baseUrl("http://music.163.com/")
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()
}

private val okHttpClient: OkHttpClient by lazy {
    OkHttpClient.Builder()
            .addInterceptor(interceptor)
            .addInterceptor(HttpLoggingInterceptor().apply { level = BODY })
            .build()
}

private val interceptor: Interceptor by lazy {
    Interceptor {
        val request = it.request()
                .newBuilder()
                .addHeader("Cookie", "appver=2.7.1")
                .addHeader("Referer", "http://music.163.com/")
                .build()
        it.proceed(request)
    }
}

@Retention(AnnotationRetention.SOURCE)
@IntDef(SONG, ALBUM, SINGER, SHEET, USER, MV, LRC, STATION)
annotation class SearchType

object NetEaseService {
    const val SONG = 1L // 歌曲
    const val ALBUM = 10L // 专辑
    const val SINGER = 100L // 歌手
    const val SHEET = 1000L // 歌单
    const val USER = 1002L // 用户
    const val MV = 1004L // MV
    const val LRC = 1006L // 歌词
    const val STATION = 1009L // 主播电台

    private val netEaseApi: NetEaseApi by lazy { netEaseRetrofit.create(NetEaseApi::class.java) }

    fun getNetEaseService(): NetEaseApi = netEaseApi
}

interface NetEaseApi {

    /**
     * 搜索
     * @param content 搜索关键字
     * @param page 分页 第 [page] 页
     * @param pageSize 分页的每页长度
     * @param type 搜索类型，值在 [NetEaseService] 中的常量
     *  分别为 [SONG], [ALBUM], [SINGER], [USER], [MV], [LRC], [STATION]
     */
    @POST("api/search/get")
    fun searchSongs(
            @Query("s") content: String,
            @Query("offset") page: Int,
            @Query("limit") pageSize: Int,
            @Query("type") @SearchType type: Long = SONG
    ): Observable<SearchItem<SongResult>>

    @POST("api/song/lyric")
    fun obtainLrc(
            @Query("id") id: Long,
            @Query("lv") lv: Int = -1,
            @Query("tv") tv: Int = -1,
            @Query("os") os: String = "pc"
    ): Observable<Lyric>

    //    @GET("")
    // 431080419
    @Streaming
    @POST("weapi/song/enhance/player/url")
    fun downloadSongs(@QueryMap req: Map<String, String>): Observable<ResponseBody>

    @POST("weapi/login")
    fun login(@QueryMap req: Map<String, String>): Observable<Any>
}
